package com.example.tools.httputils.ok;

import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.example.bean.JsonCecheEntity;
import com.example.db.SimpleEntityTemplate;
import com.example.tools.NetworkUtils;
import com.example.tools.StringUtils;
import com.example.tools.httputils.callback.OnLoadSuccessListener;
import com.example.tools.httputils.callback.OnUpdateFileCallBack;

import java.io.IOException;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * Created by Administrator on 2016/10/18.
 */

public class HttpUtils {

    private final int REQUSELTKEY = 1000;

    private final int PROGRESSKEY = 2000;

    private final String GETTYPEKEY = "AA";

    private final int SUCCESS= 1;

    private final int ERROR = 2;

    private final String ENTITYKEY = "entity";

    private final String CALLBACKKey = "callback";

    private  OkHttpClient okHttpClient;

    private static HttpUtils httputils = new HttpUtils();

    private Context context;

    private SimpleEntityTemplate<JsonCecheEntity> template;

    private HttpUtils(){}

    public static HttpUtils getInstance(){

        return httputils;
    }

    public HttpUtils Builder(Context context){
        this.context = context;
        okHttpClient = new OkHttpClient();
        template = new SimpleEntityTemplate<JsonCecheEntity>(context,JsonCecheEntity.class);
        return httputils;
    }

    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case REQUSELTKEY:
                    requselt(msg);
                    break;
                case PROGRESSKEY:
                    progressRequselt(msg);
                    break;
            }
        }
    };

    public void progressRequselt(Message msg) {
           Bundle bundle = msg.getData();
           OnUpdateFileCallBack callback = (OnUpdateFileCallBack) bundle.getSerializable(CALLBACKKey);
           String message =  bundle.getString("message");
           if(null != message){
               callback.message(message);
               return;
           }
           long tatol = bundle.getLong("tatol");
           long current = bundle.getLong("current");
           if( 0 != tatol && 0 != current){
               callback.message("正在上传...");
               callback.progress(tatol,current);
           }
    }

    public <T> void requselt(Message msg){
        Bundle bundle = msg.getData();
        OnLoadSuccessListener listener = (OnLoadSuccessListener) bundle.getSerializable(CALLBACKKey);
        int type = bundle.getInt(GETTYPEKEY);
        if(SUCCESS == type){
            T getentity = (T) bundle.getSerializable(ENTITYKEY);
            if(null == getentity ){
                listener.onFailure(new IOException(),"操作失败");
            } else {
                listener.onSuccess("操作成功",getentity);
            }
        } else if(ERROR == type){
            IOException getentity = (IOException) bundle.getSerializable(ENTITYKEY);
            listener.onFailure(getentity,"操作失败");
        }
    }

    public <T> void sendMessage( T value ,T callback,int type){
        Message message = new Message();
        message.what = REQUSELTKEY;
        Bundle bundle = new Bundle();
        bundle.putSerializable(ENTITYKEY, (Serializable) value);
        bundle.putSerializable(CALLBACKKey, (Serializable) callback);
        bundle.putInt(GETTYPEKEY,type);
        message.setData(bundle);
        handler.sendMessage(message);
    }

    public <T> void get(final Context context, final String url, final Class<T> entity, final OnLoadSuccessListener <T>listener){
        if(!NetworkUtils.isAvailable(context)){
            String cache = NonetfromDB(url);
            if(StringUtils.isEmpty(cache)){
                return;
            } else {
                sendMessage(GsonUtils.toJson(cache,entity),listener,SUCCESS);
            }
            return;
        }
        final okhttp3.Request request = new okhttp3.Request.Builder()
                .url(url)
                .build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                sendMessage(e,listener,ERROR);
            }
            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                String json = response.body().string();
                sendMessage(GsonUtils.toJson(json,entity),listener,SUCCESS);
                deletefromDB(url);
                savefromDB(url,json);
            }
        });

    }

    public <T> void post(final Context context, final String url, HashMap<String,String>map, final Class<T> entity, final OnLoadSuccessListener <T>listener){

        if(!NetworkUtils.isAvailable(context)){
           String cache = NonetfromDB(url);
            if(StringUtils.isEmpty(cache)){
                return;
            } else {
                sendMessage(GsonUtils.toJson(cache,entity),listener,SUCCESS);
            }
            return;
        }
            FormBody.Builder builder = new FormBody.Builder();
            for (String key : map.keySet()){
                String value = map.get(key);
                builder.add(key,value);
                Log.e("====="+key,"====="+value);
            }
            RequestBody body = builder.build();
            Request request = new Request.Builder()
                    .url(url)
                    .post(body)
                    .build();
            okHttpClient.newCall(request).enqueue(new Callback()
            {
                @Override
                public void onFailure(Call call,IOException e){
                    sendMessage(e,listener,ERROR);
                }
                @Override
                public void onResponse(Call call,Response response) throws IOException{
                    String json = response.body().string();
                    sendMessage(GsonUtils.toJson(json,entity),listener,SUCCESS);
                    deletefromDB(url);
                    savefromDB(url,json);
                }
            });
    }

    public void update(String actionUrl, HashMap<String, Object> paramsMap, final OnUpdateFileCallBack callBack){

        UpDateBuilder.getInstens().update(okHttpClient, actionUrl, paramsMap, new OnUpdateFileCallBack() {
            @Override
            public void progress(long total, long current) {
                sendProgressMessage(PROGRESSKEY,total,total,null,callBack);
            }

            @Override
            public void message(String message) {
                sendProgressMessage(PROGRESSKEY,0,0,message,callBack);
            }
        });
    }

    public void sendProgressMessage (int what,long tatol,long curent ,String message,OnUpdateFileCallBack callBack){
        Message handleMessage = new Message();
        handleMessage.what = what;
        Bundle bundle = new Bundle();
        bundle.putSerializable(CALLBACKKey, (Serializable) callBack);
        if(0 != tatol|| 0!=curent){
            bundle.putLong("tatol",tatol);
            bundle.putLong("current",curent);
        }
        if(null != message){
            bundle.putString("message", message);
        }
        handler.sendMessage(handleMessage);
    }

    public String NonetfromDB(String url){
       //这里需要加一个无网络提示
       try {
           JsonCecheEntity entity = template.select("url = ?",url);
           return entity.getJson();
       } catch (SQLException e) {
           Log.e(getClass().getName(),"数据库查询异常");
           e.printStackTrace();
           return null;
       }
    }


    public void savefromDB(String url , String json){
        JsonCecheEntity entity = new JsonCecheEntity();
        entity.setUrl(url);
        entity.setJson(json);
        try {
            template.insert(entity);
        } catch (SQLException e) {
            Log.e(getClass().getSimpleName(),"数据库插入错误");
            e.printStackTrace();
        }
    }

    public void deletefromDB(String parmas){
        try {
            template.delete("url = ?",parmas);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void cancelTag(Object tag)
    {
        for (Call call : okHttpClient.dispatcher().queuedCalls())
        {
            if (tag.equals(call.request().tag()))
            {
                call.cancel();
            }
        }
        for (Call call : okHttpClient.dispatcher().runningCalls())
        {
            if (tag.equals(call.request().tag()))
            {
                call.cancel();
            }
        }
    }
}

